---
image: /generated/articles-docs-renderer-render-still.png
id: render-still
title: renderStill()
crumb: '@remotion/renderer'
---

_Part of the `@remotion/renderer` package. Available from v2.3._

Renders a single frame to an image and writes it to the specified output location.

If you want to render a video, use [renderMedia()](/docs/renderer/render-media) instead.

## Example usage

You first need to bundle the project and fetch the compositions. Read [the code snippet on the site for server-side rendering](/docs/ssr) for an example how to come up with the `bundleLocation` and `composition` variables.

```ts twoslash
import {bundle} from '@remotion/bundler';
import {getCompositions, renderStill} from '@remotion/renderer';

// The composition you want to render
const compositionId = 'HelloWorld';

const bundleLocation = await bundle({
  entryPoint: require.resolve('./src/index.ts'),
});

const comps = await getCompositions(bundleLocation, {
  inputProps: {
    custom: 'data',
  },
});
const composition = comps.find((c) => c.id === compositionId);

if (!composition) {
  throw new Error(`No composition with the ID ${compositionId} found`);
}

// ---cut---

await renderStill({
  composition,
  serveUrl: bundleLocation,
  output: '/tmp/still.png',
  inputProps: {
    custom: 'data',
  },
});
```

## Arguments

Takes an object with the following properties:

### `composition`

_VideoConfig_

An object describing a composition using `id`, `width`, `height`, `fps` and `durationInFrames`, `defaultProps` and `props`.  
Call [`selectComposition()`](/docs/renderer/select-composition) or [`getCompositions()`](/docs/renderer/get-compositions) to get an array of possible configs.

### `serveUrl`

Either a local path pointing to a Remotion Webpack bundle generated by [`bundle()`](/docs/bundle) or a URL where the bundle is hosted.

### `port?`

Prefer a specific port that will be used to serve the Remotion project. If not specified, a random port will be used.

### `output`

An absolute path to where the frame should be rendered to.

### `inputProps?`

_optional_

[Input Props to pass to the selected composition of your video.](/docs/passing-props#passing-input-props-in-the-cli).  
Must be a JSON object.  
From the root component the props can be read using [`getInputProps()`](/docs/get-input-props).  
You may transform input props using [`calculateMetadata()`](/docs/calculate-metadata).

### `frame?`

_optional - default: 0_

Which frame should be rendered based on its number. Frames are zero-indexed.

From v3.2.27, negative values are allowed, with `-1` being the last frame.

### `imageFormat?`

_optional - default: "png"_

Which output format the image should have, either `png`, `jpeg`, `webp` or `pdf`.

### `scale?`

_optional_

Scales the output dimensions by a factor. See [Scaling](/docs/scaling) to learn more about this feature.

### `jpegQuality?`

_optional - default: `undefined`_

Sets the JPEG quality - must be an integer between 0 and 100 and can only be passed if `imageFormat` is set to `jpeg`.

### `puppeteerInstance?`

_optional - default `null`_

An already open [`Browser`](/docs/renderer/open-browser) instance. Use [`openBrowser()`](/docs/renderer/open-browser) to create a new instance. Reusing a browser across multiple function calls can speed up the rendering process. You are responsible for opening and closing the browser yourself. If you don't specify this option, a new browser will be opened and closed at the end.

:::note
Despite the name, not actually compatible with `puppeteer`, only with [`openBrowser()`](/docs/renderer/open-browser).
:::

### `envVariables?`

_optional - default `{}`_

An object containing key-value pairs of environment variables which will be injected into your Remotion project and which can be accessed by reading the global `process.env` object.

### `logLevel?`<AvailableFrom v="4.0.115"/>

<Options id="log" />

### `onArtifact?`<AvailableFrom v="4.0.176" />

[Handle an artifact](/docs/artifacts#using-rendermedia-renderstill-or-renderframes) that was emitted by the [`<Artifact>`](/docs/artifact) component.

### `overwrite?`

_optional - default `true`_

Whether the file should be overwritten if the output already exists.

### `browserExecutable?`<AvailableFrom v="2.3.1" />

_optional_

A string defining the absolute path on disk of the browser executable that should be used. By default Remotion will try to detect it automatically and download one if none is available.

### `onBrowserLog?`<AvailableFrom v="3.3.93" />

_optional_

Gets called when your project calls `console.log` or another method from console. See the documentation for [`renderFrames`](/docs/renderer/render-frames#onbrowserlog) for more information.

### `timeoutInMilliseconds?`<AvailableFrom v="2.6.3" />

_optional_

A number describing how long the render may take to resolve all [`delayRender()`](/docs/delay-render) calls [before it times out](/docs/timeout). Default: `30000`

### `cancelSignal?`<AvailableFrom v="3.0.15" />

_optional_

A token that allows the render to be cancelled. See: [`makeCancelSignal()`](/docs/renderer/make-cancel-signal)

### `chromiumOptions?`<AvailableFrom v="2.6.5" />

_optional_

Allows you to set certain Chromium / Google Chrome flags. See: [Chromium flags](/docs/chromium-flags).

:::note
Chromium flags need to be set at browser launch. If you pass an instance using [`puppeteerInstance`](#puppeteerinstance), options passed to `renderStill()` will not apply, but rather the flags that have been passed to [`openBrowser()`](/docs/renderer/open-browser).
:::

#### `disableWebSecurity`

_boolean - default `false`_

This will most notably disable CORS among other security features.

#### `enableMultiProcessOnLinux?`<AvailableFrom v="4.0.42" />

<Options id="enable-multiprocess-on-linux" />

#### `ignoreCertificateErrors?`

_boolean - default `false`_

Results in invalid SSL certificates, such as self-signed ones, being ignored.

#### ~`headless?`~

<Options id="disable-headless" />

#### `gl`

<Options id="gl" />

#### `userAgent`<AvailableFrom v="3.3.83"/>

Lets you set a custom user agent that the headless Chrome browser assumes.

### `mediaCacheSizeInBytes?`<AvailableFrom v="4.0.352"/>

<Options id="media-cache-size-in-bytes" />

### `offthreadVideoCacheSizeInBytes?`<AvailableFrom v="4.0.23"/>

<Options id="offthreadvideo-cache-size-in-bytes" />

### `offthreadVideoThreads?`<AvailableFrom v="4.0.261"/>

<Options id="offthreadvideo-video-threads" />

### `binariesDirectory?`<AvailableFrom v="4.0.120" />

<Options id="binaries-directory" />

### `onBrowserDownload?`<AvailableFrom v="4.0.137" />

<Options id="on-browser-download" />

### `chromeMode?`<AvailableFrom v="4.0.248" />

<Options id="chrome-mode" />

### `apiKey?`<AvailableFrom v="4.0.375"/>

<Options id="api-key" />

### ~~`dumpBrowserLogs?`~~

_optional - default `false`, deprecated in v4.0_

Deprecated in favor of [`logLevel`](#loglevel).

### ~~`quality?`~~

Renamed to `jpegQuality` in `v4.0.0`.

## Return Value

The return value is a promise that resolves to an object with the following keys:

- `buffer`: (_available from v3.3.9_) A `Buffer` that only exists if no `output` option was provided. Otherwise null.

## See also

- [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/renderer/src/render-still.ts)
- [bundle()](/docs/bundle)
- [Server-Side rendering](/docs/ssr)
- [getCompositions()](/docs/renderer/get-compositions)
- [renderMedia()](/docs/renderer/render-media)
- [renderStillOnLambda()](/docs/lambda/renderstillonlambda)
